#include "Applikation.h"
#include "InputEventReceiver.h"
#include <iostream>
//------------------------------------------------------------------------
// Konstruktor
//------------------------------------------------------------------------
Applikation::Applikation(IrrlichtDevice * const dev)
	: Entity(dev)
{
	this->init();
}
//------------------------------------------------------------------------
Applikation::Applikation(IrrlichtDevice * const dev,
						 IVideoDriver * const driv, 
						 ISceneManager * const sceneMgr, 
						 IGUIEnvironment * const guiEnv)
	: Entity(dev, driv, sceneMgr, guiEnv), m_camera(nullptr)
{
	this->init();
}
//------------------------------------------------------------------------
// Destruktor
//------------------------------------------------------------------------
Applikation::~Applikation()
{
	this->exit();
}
//------------------------------------------------------------------------
// Methoden
//------------------------------------------------------------------------
void Applikation::run(float timefactor)
{
	this->m_control->poll();

	// Camera Movement
	this->cameraMovement(timefactor);
	
	// Figuren Movement
	this->draggingMovement(timefactor);

	// Sieg testen
	this->checkVictory();

#ifdef _DEBUG
	InputEventReceiver * in = dynamic_cast<InputEventReceiver*>(this->m_device->getEventReceiver());
	if ( in->IsKeyDown(KEY_ESCAPE) ) 
		throw std::exception("Spiel beendet");
#endif
}
//------------------------------------------------------------------------
void Applikation::init()
{
	if ( Global::Konstanten::gc_UseWii )
	{
#if ControlInterfaceChanged == 0
		this->m_control.reset(new WiiMote::WiiControlling());
#endif // ControlInterfaceChanged
	}
	else
		this->m_control.reset(new DummyControlling(this->m_device));

	this->m_camera.reset(new Camera(this->m_device));
	
	this->initObjects();
}
//------------------------------------------------------------------------
void Applikation::exit()
{
}
//------------------------------------------------------------------------
void Applikation::cameraMovement(float timefactor)
{
	if ( this->m_control->pitchCameraUp() )
		this->m_camera->pitchUp(timefactor);
	if ( this->m_control->pitchCameraDown() )
		this->m_camera->pitchDown(timefactor);

	if ( this->m_control->yawCameraLeft() )
		this->m_camera->turnLeft(timefactor);
	if ( this->m_control->yawCameraRight() )
		this->m_camera->turnRight(timefactor);
}
//------------------------------------------------------------------------
void Applikation::draggingMovement(float timefactor)
{
	if ( this->m_selectedFigure )
	{
		Figure & chosenFig = *this->m_selectedFigure;

		chosenFig.move(timefactor, this->m_control->moveCursor(), *this->m_camera);

		if ( this->m_control->pitchObjectFront() )
			chosenFig.pitch();
		if ( this->m_control->pitchObjectBack() ) 
			chosenFig.pitch(false);

		if ( this->m_control->rollObjectRight() )
			chosenFig.roll();
		if ( this->m_control->rollObjectLeft() )
			chosenFig.roll(false);

		if ( this->m_control->yawObjectRight() )
			chosenFig.yaw();
		if ( this->m_control->yawObjectLeft() )
			chosenFig.yaw(false);

		if ( this->m_control->toggleSelection() )
		{
			this->dropFigure();
			this->m_selectedFigure = nullptr;
		}
	}
	else
	{
		if ( this->m_control->toggleSelection() )
		{
			this->m_selectedFigure = this->getFocusedFigure();
		}
	}

}
//------------------------------------------------------------------------
bool Applikation::isFinished() const
{
	return false;
}
//------------------------------------------------------------------------
void Applikation::checkVictory()
{
}
//------------------------------------------------------------------------
void Applikation::dropFigure()
{
}
//------------------------------------------------------------------------
Figure* Applikation::getFocusedFigure() const
{
	auto collisionMngr = this->m_sceneMgr->getSceneCollisionManager();

	auto node = collisionMngr->getSceneNodeFromScreenCoordinatesBB(this->m_control->getCursorPosition(), -1);

	if ( !node )
		return nullptr;

	return this->identifyFigureBySceneNode(node);
}
//------------------------------------------------------------------------
void Applikation::initObjects()
{
	this->initEbene();

	this->m_selectedFigure = nullptr;

	this->m_figures = Figure::createFigures(this->m_device, this->m_ebene->getCollisionStuff());

//	this->m_selectedFigure = this->m_figures.front().get();
}
//------------------------------------------------------------------------
void Applikation::initEbene()
{
	this->m_ebene.reset(new Ebene(this->m_device));
}
//------------------------------------------------------------------------
Figure* Applikation::identifyFigureBySceneNode(ISceneNode * n) const
{
	auto ID = n->getID();
	for(auto it = this->m_figures.begin(); it != this->m_figures.end(); ++it)
	{
		if ( ID == (*it)->getID() )
			return (*it).get();
	}

	return nullptr;
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
